package com.xjrsoft.common.utils;

import lombok.SneakyThrows;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * Description: 配合前端CryptoJS实现加密、解密工作。
 * CryptoJS 是一个 JavaScript 库，提供了一系列密码学函数和工具，用于加密、解密、生成摘要等任务。
 * 它支持多种加密算法，包括常见的对称加密算法（如 AES、DES）和非对称加密算法（如 RSA）。
 */
public class CryptoUtil {

    //需要前端与后端配置一致
    private final static String KEY = "1234567890123456";

    private final static String PRIVATE_KEY = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAguklcA57cTBB9mRshpSwIJronx2pOkRsOkeUHxi7w31oyGCOgxxuEynhxUX2dveKckhY6ZiPjLpOPhdgJUx3dwIDAQABAkAKnN4VHIdzYKcoU3Hc4zb4HbbYF259s8hWXTEr6DRon6dsDwoJpleCm7fq05VpD++p9tO4gGgZiendWjF7egC5AiEAunG/6aOy1NnqrmOJx3J5zdQmExggltzFzAHdu1Bl9SMCIQCzv7Gl8p6Xx8+5+xRlh8ZpN25GCxcX3WRGhdjZzSrrnQIhALllAwDA1sLxLnvaXtcE7jnOC05RX5akUctaz7HDcJ8hAiAbzjmS7DcwT46IvJhpJFnDCPocB7coz+ylJCtpdd1/2QIgPUrJhfa7d4E5RjjS/h7+ueBKH8dWAyvEuCMvEcpBFc8=";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 加密算法，使用默认的IV、KEY
     * @param content
     * @return
     */
    public static String encrypt(String content){
        return encrypt(content,KEY);
    }

    /**
     * 解密算法，使用默认的IV、KEY
     * @param content
     * @return
     */
    public static String decrypt(String content){
        return decrypt(content,KEY);
    }
    /**
     * 加密方法
     * @param content
     * @param key
     * @param iv
     * @return
     */
    public static String encrypt(String content, String key){
        try{
            // "算法/模式/补码方式"NoPadding PkcsPadding
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            int blockSize = cipher.getBlockSize();
            byte[] dataBytes = content.getBytes();
            int plaintextLength = dataBytes.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, keyspec);
            byte[] encrypted = cipher.doFinal(plaintext);
            return new String(encrypted);
        }catch (Exception e) {
            throw new RuntimeException("加密算法异常 CryptoUtil encrypt()加密方法，异常信息：" + e.getMessage());
        }
    }

    /**
     * 解密方法
     * @param content
     * @param key
     * @return
     */
    public static String decrypt(String content, String key){
        try {
            byte[] encrypted1 =  Base64.getDecoder().decode(content);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
//            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            byte[] original = cipher.doFinal(encrypted1);
            return new String(original).trim();
        } catch (Exception e) {
            throw new RuntimeException("加密算法异常 CryptoUtil decrypt()解密方法，异常信息：" + e.getMessage());
        }
    }

    /**
     * 非对称加密
     * @param content
     * @return
     */
    public static String rsaDecrypt(String content){
        return rsaDecrypt(content,KEY);
    }

    @SneakyThrows
    public static String rsaDecrypt(String content,String key) {

        // 5.私钥解密、公钥加密 ---- 解密
        byte[] encrypted1 =  Base64.getDecoder().decode(content);
         PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIVATE_KEY.getBytes()));
        KeyFactory keyFactory5 = KeyFactory.getInstance("RSA");
        PrivateKey privateKey5 = keyFactory5.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher5 = Cipher.getInstance("RSA");
        cipher5.init(Cipher.DECRYPT_MODE, privateKey5);
        byte[] result5 = cipher5.doFinal(encrypted1);
        System.out.println("公钥加密、私钥解密 ---- 解密:" + new String(result5));
        return new String(result5).trim();
    }
}